import os
import time
import logging

from appium.webdriver import WebElement
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.webdriver import WebDriver
# from appium.webdriver.webdriver import Command
# from appium.webdriver.common.touch_action import TouchAction  # Appium的辅助类，主要针对手势操作，比如滑动、长按、拖动等
# from appium.webdriver.mobilecommand import MobileCommand
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException, TimeoutException

from common.desired_caps import appium_desired
from common import logger

# from PIL import Image  # pip install Pillow  PIL 的py3版本
"""
基础页
"""


class BaseView(object):
    # 红米note4x
    nextBtn = (AppiumBy.ID, 'com.goockr.intelligentizeobc:id/goto_settings')
    allowBtn = (AppiumBy.ID, 'android:id/button1')

    # ths
    skipBtn = (AppiumBy.ID, "com.hexin.plat.android:id/skip_tv")
    imgbtn_closebtn = (AppiumBy.ID, "com.hexin.plat.android:id/imgbtn_closebtn")

    def __init__(self, driver: WebDriver):
        self.driver = driver

    @property
    def get_phone_size(self):
        """
        获取屏幕的大小
        """
        width = self.driver.get_window_size()['width']
        height = self.driver.get_window_size()['height']
        return width, height

    def swipe_left(self, duration=300):
        """
        左滑
        """
        logger.info("执行左滑")
        width, height = self.get_phone_size
        start = width * 0.9, height * 0.5
        end = width * 0.1, height * 0.5
        return self.driver.swipe(*start, *end, duration)

    def swipe_right(self, duration=300):
        """
        右滑
        """
        logger.info("执行右滑")
        width, height = self.get_phone_size
        start = width * 0.1, height * 0.5
        end = width * 0.9, height * 0.5
        return self.driver.swipe(*start, *end, duration)

    def swipe_up(self, duration):
        """
        上滑
        """
        logger.info("执行上滑")
        width, height = self.get_phone_size
        start = width * 0.5, height * 0.9
        end = width * 0.5, height * 0.1
        return self.driver.swipe(*start, *end, duration)

    def swipe_up_half(self, duration=0):
        """
        上滑一半获取所有持仓
        """
        logger.info("执行上滑一半")
        width, height = self.get_phone_size
        start = width * 0.5, height * 0.9
        end = width * 0.5, height * 0.7
        return self.driver.swipe(*start, *end, duration)

    def swipe_down(self, duration):
        """
        下滑
        """
        logger.info("执行下滑")
        width, height = self.get_phone_size
        start = width * 0.5, height * 0.1
        end = width * 0.5, height * 0.9
        return self.driver.swipe(*start, *end, duration)

    def swipe_down_half(self, duration=0):
        """
        下滑一半获取所有持仓
        """
        logger.info("执行下滑一半")
        width, height = self.get_phone_size
        start = width * 0.5, height * 0.3
        end = width * 0.5, height * 0.8
        return self.driver.swipe(*start, *end, duration)

    def skip_welcome_page(self, direction, num=3):
        """
        滑动页面跳过引导动画
        :param
        direction: str
        滑动方向，left, right, up, down
        :param
        num: 滑动次数
        :return:
        """
        direction_dic = {
            "left": "swipe_left",
            "right": "swipe_right",
            "up": "swipe_up",
            "down": "swipe_down"
        }
        time.sleep(3)
        if hasattr(self, direction_dic[direction]):
            for _ in range(num):
                getattr(self, direction_dic[direction])()  # 使用反射执行不同的滑动方法
        else:
            raise ValueError("参数{}不存在, direction可以为{}任意一个字符串".
                             format(direction, direction_dic.keys()))

    @staticmethod
    def get_element_size_location(element):
        width = element.rect["width"]
        height = element.rect["height"]
        start_x = element.rect["x"]
        start_y = element.rect["y"]
        return width, height, start_x, start_y

    def get_password_location(self, element: WebElement) -> dict:
        width, height, start_x, start_y = self.get_element_size_location(element)
        point_1 = {"x": int(start_x + width * (1 / 6) * 1), "y": int(start_y + height * (1 / 6) * 1)}
        point_2 = {"x": int(start_x + width * (1 / 6) * 3), "y": int(start_y + height * (1 / 6) * 1)}
        point_3 = {"x": int(start_x + width * (1 / 6) * 5), "y": int(start_y + height * (1 / 6) * 1)}
        point_4 = {"x": int(start_x + width * (1 / 6) * 1), "y": int(start_y + height * (1 / 6) * 3)}
        point_5 = {"x": int(start_x + width * (1 / 6) * 3), "y": int(start_y + height * (1 / 6) * 3)}
        point_6 = {"x": int(start_x + width * (1 / 6) * 5), "y": int(start_y + height * (1 / 6) * 3)}
        point_7 = {"x": int(start_x + width * (1 / 6) * 1), "y": int(start_y + height * (1 / 6) * 5)}
        point_8 = {"x": int(start_x + width * (1 / 6) * 3), "y": int(start_y + height * (1 / 6) * 5)}
        point_9 = {"x": int(start_x + width * (1 / 6) * 5), "y": int(start_y + height * (1 / 6) * 5)}
        keys = {
            1: point_1,
            2: point_2,
            3: point_3,
            4: point_4,
            5: point_5,
            6: point_6,
            7: point_7,
            8: point_8,
            9: point_9
        }
        return keys

    def gesture_password(self, element: WebElement, *pwd):
        """
        手势密码: 直接输入需要链接的点对应的数字，最多9位
        pwd: 1, 2, 3, 6, 9
        """
        if len(pwd) > 9:
            raise ValueError("需要设置的密码不能超过9位!")
        keys_dict = self.get_password_location(element)
        start_point = "TouchAction(self.driver).press(x={0}, y={1}).wait(200)". \
            format(keys_dict[pwd[0]]["x"], keys_dict[pwd[0]]["y"])
        for index in range(len(pwd) - 1):  # 0,1,2,3
            follow_point = ".move_to(x={0}, y={1}).wait(200)". \
                format(keys_dict[pwd[index + 1]]["x"],
                       keys_dict[pwd[index + 1]]["y"])
            start_point = start_point + follow_point
        full_point = start_point + ".release().perform()"
        return eval(full_point)

    def input_number(self, number: str):
        for i in number:
            self.driver.press_keycode(int(i) + 7)

    def find_element(self, locator: tuple):
        logger.info("找元素 {}".format(locator))
        return self.driver.find_element(*locator)

    def find_element_by_wait(self, locator: tuple, timeout=5) -> WebElement:
        logger.info("加载中...找元素 {}".format(locator))
        wait = WebDriverWait(self.driver, timeout)
        try:
            element = wait.until(lambda driver: driver.find_element(*locator))
            return element
        except (NoSuchElementException, TimeoutException):
            logger.error('Element not found: {}'.format(locator))

    def find_elements(self, locator: tuple, timeout=5) -> list:
        logger.info("加载中...找元素群 {}".format(locator))
        wait = WebDriverWait(self.driver, timeout)
        try:
            elements = wait.until(lambda driver: driver.find_elements(*locator))
            # logger.info(elements)
            return elements
        except (NoSuchElementException, TimeoutException):
            logger.error('Elements not found: {}'.format(locator))

    def click_element(self, locator: tuple, timeout=5):
        logger.info("点击 {}".format(locator))
        btn = self.find_element_by_wait(locator, timeout)
        if btn:
            # logger.info(btn)
            btn.click()
        else:
            logger.error("Click failed: {}".format(locator))

    """ths公用方法"""

    def check_skip_btn(self):
        """
        广告页跳过
        :return:
        """
        skipBtn = self.find_element_by_wait(self.skipBtn)
        if skipBtn:
            skipBtn.click()
        else:
            logger.info('no skip')

    def check_close_btn(self):
        """
        关闭立即升级弹窗
        :return:
        """
        closeBtn = self.find_element_by_wait(self.imgbtn_closebtn)
        if closeBtn:
            closeBtn.click()
        else:
            logger.info('no close')

    """红米note4x公用方法"""

    def check_allow_btn(self):
        try:
            allowBtn = self.driver.find_element(*self.allowBtn)
        except NoSuchElementException:
            logging.info('no allow')
        else:
            allowBtn.click()

    def check_next_btn(self):
        try:
            nextBtn = self.driver.find_element(*self.nextBtn)
        except NoSuchElementException:
            logging.info('no next')
        else:
            nextBtn.click()

    def get_time(self):
        self.now = time.strftime("%Y-%m-%d %H_%M_%S")
        return self.now

    def getScreenShot(self, module):
        time = self.get_time()
        image_file = os.path.dirname(os.path.dirname(__file__)) + '/img/%s_%s.png' % (module, time)
        logging.info('get %s screenshot' % module)
        self.driver.get_screenshot_as_file(image_file)
        return image_file

    # def get_screenshot_by_custom_size(self, module, bounds):
    #     # 自定义截取范围
    #     time = self.getTime()
    #     image_file = os.path.dirname(os.path.dirname(__file__)) + '/img/%s_%s.png' % (module, time)
    #     logging.info('get %s screenshot' % module)
    #     self.driver.get_screenshot_as_file(image_file)
    #     image = Image.open(image_file)
    #     newImage = image.crop(bounds)
    #     newImage.save(image_file)
    #     return self
    def exit(self):
        """
        退出并关闭APP
        :return:
        """
        self.driver.quit()


if __name__ == '__main__':
    appium_driver = appium_desired('ths_desired_caps.yaml')
    b = BaseView(appium_driver)
